package gruppoSoluzione.mainService.data;

import gruppoSoluzione.mainService.ServiceDB;
import gruppoSoluzione.mainService.ServiceDBLog;
import gruppoSoluzione.mainService.ServiceDate;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.text.ParseException;
import java.util.TreeSet;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * 
 * Responsabilità: Gestione del Database Effettivo
 * 
 * @author Alessandro Martinelli
 */
public class ServiceDBXML {
	
	public static final String DB_LOCATION="db";
	
	private String dbLocation=DB_LOCATION;
	
	private ServiceDBData dataStorer=new ServiceDBData();
	
	public ServiceDBXML() {
		
	}

	public ServiceDBXML(String dbLocation) {
		super();
		this.dbLocation = dbLocation;
	}

	/**
	 * Carica il DB
	 * @param toBeFilled
	 */
	public void loadDB(ServiceDB toBeFilled){
		File directory=new File(dbLocation);
		
		File[] dbFiles=directory.listFiles();
		
		for (int i = 0; i < dbFiles.length; i++) {
			if (!dbFiles[i].isDirectory()) {
				File fileXml=dbFiles[i];
				try {
					ServiceDate date=ServiceDate.fromFileName(fileXml.getName());
					TreeSet<ServiceDBLog> allLogs=loadLogFile(fileXml);
					toBeFilled.addLogs(date, allLogs);
				} catch (ParseException e) {
					/*TODO qui andare su console puo' essere ok, perche' e' la console del server
					 * a cui soltanto gli operatori accedono e non gli utenti,
					 * ma si puo' sempre considerare di rivalutare la questione*/ 
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * Salva il db
	 * @param toBeWritten
	 */
	public void saveDB(ServiceDB toBeWritten){
		
		for (ServiceDate servideDate : toBeWritten.getServiceDates()) {
			String filename=servideDate.filename();
			
			try {
				OutputStreamWriter fileWriter = new OutputStreamWriter(
					     new FileOutputStream(dbLocation+"/"+filename),
					     Charset.forName("UTF-8").newEncoder() 
					 );
				
				dataStorer.writeDB(new WriterStringWriter(fileWriter), toBeWritten.getLogsIterable(servideDate));
				
				fileWriter.close();
			}catch (IOException e) {
				/*TODO qui andare su console puo' essere ok, perche' e' la console del server
				 * a cui soltanto gli operatori accedono e non gli utenti,
				 * ma si puo' sempre considerare di rivalutare la questione*/ 
				e.printStackTrace();
			}
		}
		
	}

	
	private TreeSet<ServiceDBLog> loadLogFile(File fileXml){

		TreeSet<ServiceDBLog> logs=new TreeSet<ServiceDBLog>();
		
		try {
			
			DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
			Document document = dBuilder.parse(fileXml);
			
			NodeList registro = document.getElementsByTagName("log");
			for(int i = 0; i < registro.getLength(); i++) {
				Element libro = (Element)registro.item(i);
					String luogo = libro.getElementsByTagName("luogo").item(0).getTextContent();
					String azione = libro.getElementsByTagName("azione").item(0).getTextContent();
					String operatore = libro.getElementsByTagName("operatore").item(0).getTextContent();
					NodeList stock = libro.getElementsByTagName("stock");

					ServiceDBLog baseLog = new ServiceDBLog(luogo,azione,operatore);
					
					for (int j = 0; j < stock.getLength(); j++) {
						Element stocks = (Element)stock.item(j);
						String numero = stocks.getAttribute("quantità");
						String modello = stocks.getTextContent();
						logs.add(baseLog.generaLogSimile(Integer.parseInt(numero), modello));
					}
			}
			
		} catch (ParserConfigurationException e) {
			/*TODO qui andare su console puo' essere ok, perche' e' la console del server
			 * a cui soltanto gli operatori accedono e non gli utenti,
			 * ma si puo' sempre considerare di rivalutare la questione*/ 
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return logs;
	}
	
	
	
}
